package cn.lg.soar.boot.fc.service.impl;

import cn.lg.soar.boot.fc.entity.*;
import cn.lg.soar.boot.fc.entity.bo.UnitBo;
import cn.lg.soar.boot.fc.entity.importExcel.UnitIo;
import cn.lg.soar.boot.fc.entity.vo.BuildingEasyVo;
import cn.lg.soar.boot.fc.entity.vo.CampusEasyVo;
import cn.lg.soar.boot.fc.entity.vo.UnitEasyVo;
import cn.lg.soar.boot.fc.entity.vo.UnitVo;
import cn.lg.soar.boot.fc.service.BuildingService;
import cn.lg.soar.boot.fc.service.CampusService;
import cn.lg.soar.common.data.msg.I18n;
import cn.lg.soar.common.model.HttpResult;
import cn.lg.soar.common.model.PageQuery;
import cn.lg.soar.common.model.PageResult;
import cn.lg.soar.common.util.AssertUtil;
import cn.lg.soar.common.util.ParameterUtil;
import cn.lg.soar.core.util.easyexcel.ExcelUtil;
import cn.lg.soar.database.query.QueryParams;
import cn.lg.soar.database.query.SqueryWapper;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.micrometer.core.instrument.util.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.lg.soar.database.base.service.impl.BaseServiceImpl;
import cn.lg.soar.boot.fc.mapper.UnitMapper;
import cn.lg.soar.boot.fc.service.UnitService;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 单元表
 * @author ZhuanZ（无密码）
 * @since 2025-01-10
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
@Service
public class UnitServiceImpl extends BaseServiceImpl<UnitMapper, Unit> implements UnitService {

    @Autowired
    private CampusService campusService;

    @Autowired
    private BuildingService buildingService;

    @Override
    public HttpResult<Serializable> create(UnitBo unitBo) {
        ParameterUtil.notNull(unitBo, "数据不能为空");

        if (StringUtils.isBlank(unitBo.getParentId())) {
            return HttpResult.fail("4000", "关联校区信息不为空", "error");
        }

        Unit unit = new Unit();
        BeanUtils.copyProperties(unitBo, unit);

        // 父级的参数 关联
        String parentId = unitBo.getParentId();
        // 祖宗
        String campusIdSearch = "";
        String buildingIdSearch = "";

        // 1-3-0-0
        String[] searchStr = parentId.split("-");

        if (4 <= searchStr.length) {
            campusIdSearch = !"0".equals(searchStr[0]) ? searchStr[0]: "";
            buildingIdSearch = !"0".equals(searchStr[1]) ? searchStr[1]: "";
        }

        if (StringUtils.isNotBlank(campusIdSearch)) {
            unit.setCampusId(Long.valueOf(campusIdSearch));
        }
        if (StringUtils.isNotBlank(buildingIdSearch)) {
            unit.setBuildingId(Long.valueOf(buildingIdSearch));
        }

        boolean checkFlag =
                StringUtils.isBlank(campusIdSearch) || StringUtils.isBlank(buildingIdSearch);

        if (checkFlag) {
            return HttpResult.fail("4000", "单元关联层级不正确，请重新选择", "error");
        }

        // 父级的参数 关联 end
        AssertUtil.isTrue(this.save(unit), "创建失败");
        return HttpResult.<Serializable>success("创建成功").setData("success");
    }

    @Override
    public HttpResult<Void> update(UnitBo unitBo) {
        ParameterUtil.notNull(unitBo, "数据不能为空");

        Unit unit = new Unit();
        BeanUtils.copyProperties(unitBo, unit);
        // 父级的参数 关联
        String parentId = unitBo.getParentId();
        // 祖宗
        String campusIdSearch = "";
        String buildingIdSearch = "";

        // 1-3-0-0
        String[] searchStr = parentId.split("-");

        if (4 <= searchStr.length) {
            campusIdSearch = !"0".equals(searchStr[0]) ? searchStr[0]: "";
            buildingIdSearch = !"0".equals(searchStr[1]) ? searchStr[1]: "";
        }

        if (StringUtils.isNotBlank(campusIdSearch)) {
            unit.setCampusId(Long.valueOf(campusIdSearch));
        }
        if (StringUtils.isNotBlank(buildingIdSearch)) {
            unit.setBuildingId(Long.valueOf(buildingIdSearch));
        }

        boolean checkFlag =
                StringUtils.isBlank(campusIdSearch) || StringUtils.isBlank(buildingIdSearch);

        if (checkFlag) {
            return HttpResult.fail("4000", "单元关联层级不正确，请重新选择", "error");
        }

        // 父级的参数 关联 end
        AssertUtil.isTrue(this.updateById(unit), "更新失败");
        return HttpResult.success("更新成功");
    }

    @Override
    public Unit getData(Long id) {
        if (Objects.isNull(id)) {
            return new Unit();
        }

        Unit unit = this.getOne(Wrappers.<Unit>lambdaQuery().eq(Unit::getId, id));
        if (null == unit) {
            unit = new Unit();
        }
        return unit;
    }

    @Override
    public UnitVo getVoData(Long id) {
        UnitVo unitVo = new UnitVo();
        if (Objects.isNull(id)) {
            return unitVo;
        }
        Unit unit = this.getData(id);
        BeanUtils.copyProperties(unit, unitVo);
        // 前台查看 所属的校区楼栋，通过vo中的id前台进行绑定

        // 校区 简单vo绑定
        CampusEasyVo campusEasyVo = campusService.getEasyVoData(unitVo.getCampusId());
        unitVo.setCampusEasyVo(campusEasyVo);

        // 楼栋 简单vo
        BuildingEasyVo buildingEasyVo = buildingService.getEasyVoData(unitVo.getBuildingId());
        unitVo.setBuildingEasyVo(buildingEasyVo);

        return unitVo;
    }

    @Override
    public UnitEasyVo getEasyVoData(Long id) {

        UnitEasyVo unitEasyVo = new UnitEasyVo();
        if (Objects.isNull(id)) {
            return unitEasyVo;
        }

        Unit unit = this.getData(id);
        BeanUtils.copyProperties(unit, unitEasyVo);
        return unitEasyVo;
    }

    @Override
    public PageResult<UnitVo> queryResultVo(PageQuery pageQuery, QueryParams params) {
        PageResult<UnitVo> pageResultVo = new PageResult<>();

        SqueryWapper<Unit> squeryWapper = new SqueryWapper<>(Unit.class);
        PageResult<Unit> pageResult = squeryWapper.query(this, pageQuery, params);

        BeanUtils.copyProperties(pageResult, pageResultVo);
        // vo封装
        List<UnitVo> list = new ArrayList<>();
        pageResult.getList().forEach(item-> {

            UnitVo unitVo = new UnitVo();
            BeanUtils.copyProperties(item, unitVo);

            // 校区对象简单vo
            CampusEasyVo campusEasyVo = campusService.getEasyVoData(item.getCampusId());
            unitVo.setCampusEasyVo(campusEasyVo);

            // 楼栋对象简单vo
            BuildingEasyVo buildingEasyVo = buildingService.getEasyVoData(item.getBuildingId());
            unitVo.setBuildingEasyVo(buildingEasyVo);

            list.add(unitVo);
        });
        pageResultVo.setList(list);
        return pageResultVo;
    }

    @Override
    public List<UnitVo> getListVoByOtherId(QueryParams params) {

        List<UnitVo> listVo = new ArrayList<>();
        // 架构get 请求参数格式：
//        [name-like~楼栋1, area-like~100]
        List<String> f = params.getF();
        if (1 >= f.size()) {
            return listVo;
        }

        String campusIdStr = f.get(0);
        String buildingIdStr = f.get(1);
        if (-1 >= campusIdStr.indexOf("campusId")) {
            return listVo;
        }
        if (-1 >= buildingIdStr.indexOf("buildingId")) {
            return listVo;
        }

        String[] campTemp = campusIdStr.split(params.VALUE_JOIN);
        String[] buildTemp = buildingIdStr.split(params.VALUE_JOIN);

        if (1 >= campTemp.length || 1 >= buildTemp.length) {
            return listVo;
        }

        String campusId = campTemp[1];
        String buildingId = buildTemp[1];

        List<Unit> listT = list(Wrappers.<Unit>lambdaQuery().eq(Unit::getCampusId, campusId).eq(Unit::getBuildingId,
                buildingId));

        listT.forEach(item-> {

            UnitVo unitVo = new UnitVo();
            BeanUtils.copyProperties(item, unitVo);
            listVo.add(unitVo);
        });
        return listVo;
    }

    @Override
    public List<Unit> getListByOtherId(QueryParams params) {

        List<Unit> list = new ArrayList<>();
        // 架构get 请求参数格式：
//        [name-like~楼栋1, area-like~100]
        List<String> f = params.getF();
        if (1 >= f.size()) {
            return list;
        }

        String campusIdStr = f.get(0);
        String buildingIdStr = f.get(1);
        if (-1 >= campusIdStr.indexOf("campusId")) {
            return list;
        }
        if (-1 >= buildingIdStr.indexOf("buildingId")) {
            return list;
        }

        String[] campTemp = campusIdStr.split(params.VALUE_JOIN);
        String[] buildTemp = buildingIdStr.split(params.VALUE_JOIN);

        if (1 >= campTemp.length || 1 >= buildTemp.length) {
            return list;
        }

        String campusId = campTemp[1];
        String buildingId = buildTemp[1];

        list = list(Wrappers.<Unit>lambdaQuery().eq(Unit::getCampusId, campusId).eq(Unit::getBuildingId,
                buildingId));
        return list;
    }

    @Override
    public Unit getByCIDAndBIDAndName(Long campusId, Long buildingId, String name) {
        if (Objects.isNull(campusId) || Objects.isNull(buildingId) || StringUtils.isBlank(name)) {
            return new Unit();
        }
        return this.getFirst(Wrappers.<Unit>lambdaQuery().eq(Unit::getCampusId, campusId).eq(Unit::getBuildingId,
                buildingId).eq(Unit::getName, name));
    }

    @Override
    public void exportExcel(String filename, QueryParams params, HttpServletResponse resp) {
        SqueryWapper<Unit> squeryWapper = new SqueryWapper<>(Unit.class);

        if (null == squeryWapper) {
            squeryWapper = new SqueryWapper<>(Unit.class);
        }
        QueryWrapper<Unit> wrapper = Wrappers.query();
        squeryWapper.setWhere(params.getF(), wrapper);
        squeryWapper.setSelect(params.getFields(), wrapper);
        squeryWapper.setOrderBy(params.getOrderBy(), wrapper);

        List<Unit> list = new ArrayList<>();
        List<UnitIo> listIo = new ArrayList<>();
        if (null == params.getF()) {
            list.add(new Unit());
            listIo.add(new UnitIo());
        } else {
            list = this.list(wrapper);
        }

        list.forEach(item->{
            Unit unit = this.getData(item.getId());

            UnitIo unitIo = new UnitIo();
            BeanUtils.copyProperties(item, unitIo);
            unitIo.setCampusName(campusService.getEasyVoData(unit.getCampusId()).getName());
            unitIo.setBuildingName(buildingService.getEasyVoData(unit.getBuildingId()).getName());

            listIo.add(unitIo);
        });

        if (StringUtils.isBlank(filename)) {
            filename = "单元";
        }

        // 导出
        ExcelUtil.exportExcel(filename, listIo, resp);
    }

    @Override
    public HttpResult<Void> importExcel(MultipartFile files) {
        List<UnitIo> dataList;
        try {
            dataList = EasyExcel.read(files.getInputStream()).head(UnitIo.class).sheet()
                    .doReadSync();
        } catch (Exception e) {
            return HttpResult.fail("B0000", I18n.build("数据格式存在问题，无法读取！"));
        }
        if (0 >= dataList.size()) {
            return HttpResult.fail("B0000", I18n.build("无数据，无法读取！"));
        }

        AtomicInteger successNum = new AtomicInteger();
        AtomicInteger errorNum = new AtomicInteger();
        dataList.forEach(item-> {
            importExcelHelper(item, successNum, errorNum);
        });

        String message = "总数：" + dataList.size() + "; 成功：" + successNum.get() + "; 失败：" + errorNum.get();
        return HttpResult.success("导入成功 " + message);
    }

    @Override
    public HttpResult<Serializable> updateSort(List<Map<String, Integer>> sortedData) {
        if (null == sortedData || 0 >= sortedData.size()) {
            return HttpResult.fail("4000", "排序数据不可为空", "error");
        }

        sortedData.forEach(item-> {

            if (!item.containsKey("id") || !item.containsKey("orders")) {
                return;
            }

            Long id = item.get("id").longValue();;
            int orders = item.get("orders");

            Unit unit = new Unit();
            unit.setId(id);
            unit.setOrders(orders);
            this.updateById(unit);
        });
        return HttpResult.success("排序成功");
    }

    /**
     * 导入数据帮助者
     * @param unitIo
     * @param successNum
     * @param errorNum
     */
    private void importExcelHelper (UnitIo unitIo, AtomicInteger successNum, AtomicInteger errorNum) {


        String campusName = unitIo.getCampusName();
        String buildingName = unitIo.getBuildingName();

        boolean checkFlag =
                StringUtils.isBlank(campusName) || StringUtils.isBlank(buildingName) || StringUtils.isBlank(unitIo.getName());

        if (checkFlag) {
            errorNum.getAndIncrement();
            return;
        }

        Unit unit = new Unit();
        BeanUtils.copyProperties(unitIo, unit);

        Campus campus = campusService.getByName(campusName);

        if (null == (campus) && Objects.isNull(campus.getId())) {
            errorNum.getAndIncrement();
            return;
        }
        unit.setCampusId(campus.getId());

        Building building = buildingService.getByCampusIdAndName(campus.getId(), buildingName);

        if (null == (building) || Objects.isNull(building.getId())) {
            errorNum.getAndIncrement();
            return;
        }
        unit.setBuildingId(building.getId());

        unit.setParentId(unit.getCampusId() + "-" + unit.getBuildingId() + "-0-0");

        try {
            this.save(unit);
            successNum.getAndIncrement();
        } catch (Exception e) {
            e.printStackTrace();
            errorNum.getAndIncrement();
            return;
        }

    }
}
